import 'dart:async';

import 'package:chewie/chewie.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';

class MyVideo extends StatefulWidget {
  const MyVideo({super.key});

  @override
  State<MyVideo> createState() {
    return _MyVideoState();
  }
}

class _MyVideoState extends State<MyVideo> {
  // 指示video资源是否加载完成，加载完成后会获得总时长和视频长宽比等信息
  bool _videoInit = false;

  // video控件管理器
  VideoPlayerController? _controller;

  // 记录video播放进度
  Duration _position = const Duration(seconds: 0);

  // 记录播放控件ui是否显示(进度条，播放按钮，全屏按钮等等)
  Timer? _timer; // 计时器，用于延迟隐藏控件ui
  bool _hidePlayControl = true; // 控制是否隐藏控件ui
  double _playControlOpacity = 0; // 通过透明度动画显示/隐藏控件ui
  // 记录是否全屏
  bool get _isFullScreen =>
      MediaQuery.of(context).orientation == Orientation.landscape;

  ChewieController? _chewieController;

  @override
  void initState() {
    _urlChange(); // 初始进行一次url加载
    _chewieController = ChewieController(
        videoPlayerController: _controller!,
        autoPlay: true,
        looping: true,
        deviceOrientationsAfterFullScreen: [
          DeviceOrientation.portraitUp,
          DeviceOrientation.portraitDown
        ]);
    super.initState();
  }

  @override
  void didUpdateWidget(MyVideo oldWidget) {
    super.didUpdateWidget(oldWidget);
  }

  @override
  void dispose() {
    if (_controller != null) {
      // 组件销毁时清理下
      _controller?.removeListener(_videoListener);
      _controller?.dispose();
      _chewieController?.dispose();
    }
    super.dispose();
  }

  void _urlChange() {
    if (_controller != null) {
      // 如果控制器存在，清理掉重新创建
      _controller?.removeListener(_videoListener);
      _controller?.dispose();
    }
    setState(() {
      // 重置组件参数
      _hidePlayControl = true;
      _videoInit = false;
      _position = const Duration(seconds: 0);
    });

    // _controller = VideoPlayerController.networkUrl(Uri.parse('https://media.w3.org/2010/05/sintel/trailer.mp4'));
    _controller = VideoPlayerController.asset("assets/video1.mp4");
    _controller?.initialize();
    _controller?.addListener(_videoListener);
    Future.delayed(const Duration(seconds: 5)).then((value) => {
          setState(() {
            _videoInit = true;
          })
        });
  }

  void _videoListener() async {
    Duration res = await _controller!.position ?? const Duration();
    if (res >= _controller!.value.duration) {
      _controller!.pause();
      _controller!.seekTo(const Duration(seconds: 0));
    }
    setState(() {
      _position = res;
    });
  }

  void _togglePlayControl() {
    setState(() {
      if (_hidePlayControl) {
        // 如果隐藏则显示
        _hidePlayControl = false;
        _playControlOpacity = 1;
        _startPlayControlTimer(); // 开始计时器，计时后隐藏
      } else {
        // 如果显示就隐藏
        if (_timer != null) _timer!.cancel(); // 有计时器先移除计时器
        _playControlOpacity = 0;
        Future.delayed(const Duration(milliseconds: 300)).whenComplete(() {
          _hidePlayControl = true; // 延迟300ms(透明度动画结束)后，隐藏
        });
      }
    });
  }

  void _startPlayControlTimer() {
    // 计时器，用法和前端js的大同小异
    if (_timer != null) _timer!.cancel();
    _timer = Timer(const Duration(seconds: 3), () {
      // 延迟3s后隐藏
      setState(() {
        _playControlOpacity = 0;
        Future.delayed(const Duration(milliseconds: 300)).whenComplete(() {
          _hidePlayControl = true;
        });
      });
    });
  }

  void _toggleFullScreen() {
    setState(() async {
      var currentOrientation = MediaQuery.of(context).orientation;

      if (currentOrientation == Orientation.portrait) {
        await SystemChrome.setPreferredOrientations([
          DeviceOrientation.landscapeLeft,
          DeviceOrientation.landscapeRight
        ]);
      } else {
        await SystemChrome.setPreferredOrientations(
            [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
      }
      _startPlayControlTimer(); // 操作完控件开始计时隐藏
    });
  }

  durationToTime(Duration duration) {
    String hours = duration.inHours.toString().padLeft(0, '2');
    String minutes =
        duration.inMinutes.remainder(60).toString().padLeft(2, '0');
    String seconds =
        duration.inSeconds.remainder(60).toString().padLeft(2, '0');
    return "$hours:$minutes:$seconds";
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: _isFullScreen
          ? MediaQuery.of(context).size.height
          : MediaQuery.of(context).size.width,
      height: _isFullScreen
          ? MediaQuery.of(context).size.width
          : MediaQuery.of(context).size.width / 16 * 9,
      color: Colors.black,
      child: Stack(
        // 因为控件ui和视频是重叠的，所以要用定位了
        children: <Widget>[
          GestureDetector(
            // 手势组件
            onTap: () {
              // 点击显示/隐藏控件ui
              _togglePlayControl();
            },
            child: _videoInit
                ? Center(
                    child: Chewie(
                      controller: _chewieController!,
                    ),
                  )
                : const Center(
                    // 没加载完成时显示转圈圈loading
                    child: SizedBox(
                      width: 20,
                      height: 20,
                      child: CircularProgressIndicator(),
                    ),
                  ),
          ),
          Positioned(
            left: 0,
            bottom: 0,
            child: Offstage(
              offstage: _hidePlayControl,
              child: AnimatedOpacity(
                opacity: _playControlOpacity,
                duration: const Duration(milliseconds: 300),
                child: Container(
                  // 底部控件的容器
                  width: _isFullScreen
                      ? MediaQuery.of(context).size.height
                      : MediaQuery.of(context).size.width,
                  height: 40,
                  decoration: const BoxDecoration(
                    gradient: LinearGradient(
                      // 来点黑色到透明的渐变优雅一下
                      begin: Alignment.bottomCenter,
                      end: Alignment.topCenter,
                      colors: [
                        Color.fromRGBO(0, 0, 0, .7),
                        Color.fromRGBO(0, 0, 0, .1)
                      ],
                    ),
                  ),
                  child: _videoInit
                      ? Row(
                          // 加载完成时才渲染,flex布局
                          children: <Widget>[
                            IconButton(
                              // 播放按钮
                              padding: EdgeInsets.zero,
                              iconSize: 26,
                              icon: Icon(
                                // 根据控制器动态变化播放图标还是暂停
                                _controller!.value.isPlaying
                                    ? Icons.pause
                                    : Icons.play_arrow,
                                color: Colors.white,
                              ),
                              onPressed: () {
                                setState(() {
                                  // 同样的，点击动态播放或者暂停
                                  _controller!.value.isPlaying
                                      ? _controller!.pause()
                                      : _controller!.play();
                                  _startPlayControlTimer(); // 操作控件后，重置延迟隐藏控件的timer
                                });
                              },
                            ),
                            Flexible(
                              // 相当于前端的flex: 1
                              child: VideoProgressIndicator(
                                _controller!,
                                allowScrubbing: true, // 允许手势操作进度条
                                padding: const EdgeInsets.all(0),
                                colors: VideoProgressColors(
                                  // 配置进度条颜色，也是video_player现成的，直接用
                                  playedColor:
                                      Theme.of(context).primaryColor, // 已播放的颜色
                                  bufferedColor: const Color.fromRGBO(
                                      255, 255, 255, .5), // 缓存中的颜色
                                  backgroundColor: const Color.fromRGBO(
                                      255, 255, 255, .2), // 为缓存的颜色
                                ),
                              ),
                            ),
                            Container(
                              // 播放时间
                              margin: const EdgeInsets.only(left: 10),
                              child: Text(
                                // durationToTime是通过Duration转成hh:mm:ss的格式，自己实现。
                                durationToTime(_position) +
                                    '/' +
                                    durationToTime(_controller!.value.duration),
                                style: const TextStyle(color: Colors.white),
                              ),
                            ),
                            IconButton(
                              // 全屏/横屏按钮
                              padding: EdgeInsets.zero,
                              iconSize: 26,
                              icon: Icon(
                                // 根据当前屏幕方向切换图标
                                _isFullScreen
                                    ? Icons.fullscreen_exit
                                    : Icons.fullscreen,
                                color: Colors.white,
                              ),
                              onPressed: () {
                                // 点击切换是否全屏
                                _toggleFullScreen();
                              },
                            ),
                          ],
                        )
                      : Container(),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
